package com.wing.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.cabinet.model.request.CellInventoryInoutDetailForm;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.JsonResult;
import com.wing.order.dao.CabInventoryProductDao;
import com.wing.order.model.entity.CabInventoryProduct;
import com.wing.order.model.entity.CabInventoryProductRecord;
import com.wing.order.model.request.CabInventoryProductForm;
import com.wing.order.model.response.CabInventoryProductVO;
import com.wing.platform.feign.PlatformClient;
import com.wing.platform.order.model.response.InventoryProductVO;
import com.wing.product.model.entity.ProductPack;
import com.wing.product.service.ProductPackService;
import com.wing.warehouse.model.entity.WarehouseInventoryType;
import com.wing.warehouse.service.WarehouseInventoryTypeService;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 产品库存-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class CabInventoryProductServiceImpl extends ServiceImpl<CabInventoryProductDao, CabInventoryProduct> implements CabInventoryProductService {

    @Autowired
    private CabInventoryProductDao cabInventoryProductDao;

    @Autowired
    private CabInventoryProductRecordService inventoryProductRecordService;

    @Autowired
    private PlatformClient platformClient;

    @Autowired
    private WarehouseInventoryTypeService warehouseInventoryTypeService;

    @Autowired
    private ProductPackService productPackService;

//    @Autowired
//    private CellInventorySpaceService cellInventorySpaceService;

//    @Autowired
//    private StorageInventorySpaceService storageInventorySpaceService;

    @Override
    public int add(CabInventoryProductForm cabInventoryProductForm) {

        //校验

        CabInventoryProduct cabInventoryProduct =new CabInventoryProduct();
        CopyOptions copyOptions = CopyOptions.create()
        .setEditable(CabInventoryProduct.class)
        .setIgnoreError(true)
        .setIgnoreNullValue(true);
        BeanUtil.copyProperties(cabInventoryProductForm, cabInventoryProduct, copyOptions);

        return baseMapper.insert(cabInventoryProduct);
    }

    @Override
    public List<CabInventoryProductVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<CabInventoryProductVO> pageList4app(Page page, Map<String, Object> params) {
        List<CabInventoryProductVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public CabInventoryProductVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }

    @Override
    public CabInventoryProduct getInventoryProductVOBySkuCode(String skuCode,Long warehouseId,Integer sourceType) {
        return cabInventoryProductDao.getCabInventoryProductVOBySkuCode(skuCode,warehouseId,sourceType);
    }

    @Override
    public List<CabInventoryProduct> getInventoryProductByType() {
        QueryWrapper<CabInventoryProduct> wrapper = new QueryWrapper<>();
        wrapper.eq("type",0);
        List<CabInventoryProduct> list = cabInventoryProductDao.selectList(wrapper);
        return list;
    }

    @Override
    public List<Object> getCabInventoryProductBySkuCodeAndType(String skuCode) {
        List<Object> list = Lists.newArrayList();
        // 查询本地库存
        List<CabInventoryProductVO> inventoryProductVOList = cabInventoryProductDao.getCabInventoryProductBySkuCodeAndType(skuCode);
        // 查询平台端库存
        JsonResult<List<InventoryProductVO>> jsonResult = platformClient.getRepertoryBySkuCodeByCompanyId(skuCode, String.valueOf(JwtUtils.getEnterpriseId()));
        List<InventoryProductVO> platInventoryProductList = jsonResult.getData();
        if(platInventoryProductList != null){
            for (InventoryProductVO item:platInventoryProductList){
                item.setSourceType(Long.valueOf(1));
                list.add(item);
            }
        }
        list.addAll(inventoryProductVOList);
        return list;
    }

    @Override
    public List<CabInventoryProduct> getInventoryProductBySkuType(String skuCode) {
        LambdaQueryWrapper<CabInventoryProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CabInventoryProduct::getSkuCode,skuCode);
        return cabInventoryProductDao.selectList(wrapper);
    }

    @Override
    @Transactional
    public void inventoryOut(List<CellInventoryInoutDetailForm> list) {
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        Long creator=JwtUtils.getLoginUserId();
        String creatorName=JwtUtils.getLoginUsername();
        if (CollectionUtil.isNotEmpty(list)){
            for (CellInventoryInoutDetailForm cellInventoryInoutDetailForm:list){
                List<CabInventoryProduct> inventoryProducts=cabInventoryProductDao.selectList(new QueryWrapper<CabInventoryProduct>().eq("sku_code",cellInventoryInoutDetailForm.getSkuCode()).eq("enterprise_code",enterpriseCode).eq("quantity_pack_unit",cellInventoryInoutDetailForm.getQuantityPackUnit()));
                Integer sum=getSumQuantity(inventoryProducts);
                if (inventoryProducts.size()==0){
//                    throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+"无库存");
                    break;
                }
                if (sum<cellInventoryInoutDetailForm.getQuantity()){
//                    throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+"当前库存["+sum+"],上货数量为["+cellInventoryInoutDetailForm.getQuantity()+"],库存不足");
                }
                Integer quantityOut=cellInventoryInoutDetailForm.getQuantity();
                if (quantityOut<0){
                    quantityOut=quantityOut*-1;
                }
                boolean isContinue=true;
                for (CabInventoryProduct cabInventoryProduct:inventoryProducts){
                    if (cabInventoryProduct.getQuantity()<=0){
                        continue;
                    }
                    CabInventoryProduct cabInventoryProduct4Update=new CabInventoryProduct();
                    cabInventoryProduct4Update.setId(cabInventoryProduct.getId());
                    Integer quantityDbCurrent=cabInventoryProduct.getQuantity();
                    Integer quantityPackDbCurrent=cabInventoryProduct.getQuantityPack();
                    if (quantityPackDbCurrent==null){
                        quantityPackDbCurrent=0;
                    }
                    Integer quantityAfter=null;
                    Integer quantityPackAfter=null;
                    Integer quantityOutCurrent=0;
                    if(quantityOut>quantityDbCurrent){
//                        cabInventoryProductDao.deleteById(cabInventoryProduct.getId());
                        quantityAfter=0;
                        quantityPackAfter=0;
                        cabInventoryProduct4Update.setQuantity(quantityAfter);
                        cabInventoryProduct4Update.setQuantityPack(quantityPackAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);

                        quantityOut=quantityOut-quantityDbCurrent;
                        quantityOutCurrent=quantityDbCurrent;

                    }else if(quantityOut.equals(quantityDbCurrent)){
//                        cabInventoryProductDao.deleteById(cabInventoryProduct.getId());
                        quantityAfter=0;
                        quantityPackAfter=0;
                        cabInventoryProduct4Update.setQuantity(quantityAfter);
                        cabInventoryProduct4Update.setQuantityPack(quantityPackAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);

                        quantityOutCurrent=quantityDbCurrent;

                        isContinue=false;
                    }else {

                        quantityAfter=quantityDbCurrent-quantityOut;
                        quantityPackAfter=quantityPackDbCurrent-quantityOut*cellInventoryInoutDetailForm.getQuantityPackUnit();
                        cabInventoryProduct4Update.setQuantity(quantityAfter);
                        cabInventoryProduct4Update.setQuantityPack(quantityPackAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);
                        quantityOutCurrent=quantityOut;

                        isContinue=false;

                    }


                    CabInventoryProductRecord cabInventoryProductRecord=new CabInventoryProductRecord();
                    cabInventoryProductRecord.setSkuCode(cellInventoryInoutDetailForm.getSkuCode());
                    cabInventoryProductRecord.setEnterpriseCode(enterpriseCode);
                    cabInventoryProductRecord.setQuantity(quantityOutCurrent*-1);
                    cabInventoryProductRecord.setQuantityCurrent(quantityDbCurrent);
                    cabInventoryProductRecord.setQuantityAfter(quantityAfter);
                    // 查询包装方式
                    ProductPack productPack = productPackService.getById(cellInventoryInoutDetailForm.getPackId());
                    cabInventoryProductRecord.setQuantityPack(quantityOutCurrent*-1*productPack.getBaseRate());
                    cabInventoryProductRecord.setQuantityPackUnit(productPack.getBaseRate());
                    cabInventoryProductRecord.setQuantityPackCurrent(quantityPackDbCurrent);
                    cabInventoryProductRecord.setQuantityPackAfter(quantityPackAfter);
                    cabInventoryProductRecord.setWarehouseId(cabInventoryProduct.getWarehouseId());
                    cabInventoryProductRecord.setType(CabInventoryProductRecord.Type.out);
                    cabInventoryProductRecord.setCreator(creator);
                    cabInventoryProductRecord.setCreatorName(creatorName);
                    cabInventoryProductRecord.setPackId(cellInventoryInoutDetailForm.getPackId());
                    cabInventoryProductRecord.setPackName(cellInventoryInoutDetailForm.getPackName());
                    cabInventoryProductRecord.setUnitName(cellInventoryInoutDetailForm.getUnitName());
                    WarehouseInventoryType warehouseInventoryType = warehouseInventoryTypeService.getOne(new QueryWrapper<WarehouseInventoryType>().eq("code", "LY_CK"));
                    if(null != warehouseInventoryType){
                        cabInventoryProductRecord.setWarehouseInventoryTypeId(warehouseInventoryType.getId());
                    }
                    inventoryProductRecordService.save(cabInventoryProductRecord);
                    if (!isContinue){
                        break;
                    }
                }

            }
        }
    }


    @Override
    @Transactional
    public void inventoryIn(List<CellInventoryInoutDetailForm> list) {
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        Long creator=JwtUtils.getLoginUserId();
        String creatorName=JwtUtils.getLoginUsername();
        if (CollectionUtil.isNotEmpty(list)){
            for (CellInventoryInoutDetailForm cellInventoryInoutDetailForm:list){
                List<CabInventoryProduct> inventoryProducts=cabInventoryProductDao.selectList(new QueryWrapper<CabInventoryProduct>().eq("sku_code",cellInventoryInoutDetailForm.getSkuCode()).eq("enterprise_code",enterpriseCode));
                Integer sum=getSumQuantity(inventoryProducts);
                if (inventoryProducts.size()==0){
//                    throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+"无库存");
                    break;
                }
                if (sum<cellInventoryInoutDetailForm.getQuantity()){
//                    throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+"当前库存["+sum+"],上货数量为["+cellInventoryInoutDetailForm.getQuantity()+"],库存不足");
                }
                Integer quantityOut=cellInventoryInoutDetailForm.getQuantity();
                if (quantityOut<0){
                    quantityOut=quantityOut*-1;
                }
                boolean isContinue=true;
                for (CabInventoryProduct cabInventoryProduct:inventoryProducts){
                    if (cabInventoryProduct.getQuantity()<=0){
                        continue;
                    }
                    CabInventoryProduct cabInventoryProduct4Update=new CabInventoryProduct();
                    cabInventoryProduct4Update.setId(cabInventoryProduct.getId());
                    Integer quantityDbCurrent=cabInventoryProduct.getQuantity();
                    if (quantityDbCurrent==null){
                        quantityDbCurrent=0;
                    }
                    Integer quantityAfter=null;
                    Integer quantityOutCurrent=0;
                    if(quantityOut>quantityDbCurrent){
//                        cabInventoryProductDao.deleteById(cabInventoryProduct.getId());
                        quantityAfter=0;
                        cabInventoryProduct4Update.setQuantity(quantityAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);

                        quantityOut=quantityOut-quantityDbCurrent;
                        quantityOutCurrent=quantityDbCurrent;

                    }else if(quantityOut.equals(quantityDbCurrent)){
//                        cabInventoryProductDao.deleteById(cabInventoryProduct.getId());
                        quantityAfter=0;
                        cabInventoryProduct4Update.setQuantity(quantityAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);

                        quantityOutCurrent=quantityDbCurrent;

                        isContinue=false;
                    }else {

                        quantityAfter=quantityDbCurrent-quantityOut;
                        cabInventoryProduct4Update.setQuantity(quantityAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);
                        quantityOutCurrent=quantityOut;

                        isContinue=false;

                    }


                    CabInventoryProductRecord cabInventoryProductRecord=new CabInventoryProductRecord();
                    cabInventoryProductRecord.setSkuCode(cellInventoryInoutDetailForm.getSkuCode());
                    cabInventoryProductRecord.setEnterpriseCode(enterpriseCode);
                    cabInventoryProductRecord.setQuantity(quantityOutCurrent*-1);
                    cabInventoryProductRecord.setQuantityCurrent(quantityDbCurrent);
                    cabInventoryProductRecord.setQuantityAfter(quantityAfter);
                    cabInventoryProductRecord.setWarehouseId(cabInventoryProduct.getWarehouseId());
                    cabInventoryProductRecord.setType(CabInventoryProductRecord.Type.out);
                    cabInventoryProductRecord.setCreator(creator);
                    cabInventoryProductRecord.setCreatorName(creatorName);
                    inventoryProductRecordService.save(cabInventoryProductRecord);
                    if (!isContinue){
                        break;
                    }
                }

            }
        }
    }

    @Override
    @Transactional
    public void inventoryOut4Load(List<CellInventoryInoutDetailForm> list) {
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        Long creator=JwtUtils.getLoginUserId();
        String creatorName=JwtUtils.getLoginUsername();
        if (CollectionUtil.isNotEmpty(list)){
            for (CellInventoryInoutDetailForm cellInventoryInoutDetailForm:list){
                List<CabInventoryProduct> inventoryProducts=cabInventoryProductDao.selectList(new QueryWrapper<CabInventoryProduct>().eq("sku_code",cellInventoryInoutDetailForm.getSkuCode()).eq("enterprise_code",enterpriseCode));
//                Integer sum=getSumQuantityReal(inventoryProducts);
                Integer sum=getSumQuantityReal(cellInventoryInoutDetailForm.getSkuCode(),cellInventoryInoutDetailForm.getQuantityPackUnit(),inventoryProducts);
                if (inventoryProducts.size()==0){
                    throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+"无库存");
                }
                if (sum <cellInventoryInoutDetailForm.getQuantity()){
                    throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+"当前库存["+sum+"],上货数量为["+cellInventoryInoutDetailForm.getQuantity()+"],库存不足");
                }
                Integer quantityOut=cellInventoryInoutDetailForm.getQuantity();
                if (quantityOut<0){
                    quantityOut=quantityOut*-1;
                }
                boolean isContinue=true;
                for (CabInventoryProduct cabInventoryProduct:inventoryProducts){
                    if (cabInventoryProduct.getQuantityReal()<=0){
                        continue;
                    }
                    CabInventoryProduct cabInventoryProduct4Update=new CabInventoryProduct();
                    cabInventoryProduct4Update.setId(cabInventoryProduct.getId());
                    Integer quantityDbCurrent=cabInventoryProduct.getQuantityReal();
                    Integer quantityAfter=null;

                    Integer quantityOutCurrent=0;
                    if(quantityOut>quantityDbCurrent){
//                        cabInventoryProductDao.deleteById(cabInventoryProduct.getId());
                        quantityAfter=0;
                        cabInventoryProduct4Update.setQuantityReal(quantityAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);

                        quantityOut=quantityOut-quantityDbCurrent;
                        quantityOutCurrent=quantityDbCurrent;

                    }else if(quantityOut.equals(quantityDbCurrent)){
//                        cabInventoryProductDao.deleteById(cabInventoryProduct.getId());
                        quantityAfter=0;
                        cabInventoryProduct4Update.setQuantityReal(quantityAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);
                        quantityOutCurrent=quantityDbCurrent;

                        isContinue=false;
                    }else {
                        quantityAfter=quantityDbCurrent-quantityOut;
                        cabInventoryProduct4Update.setQuantityReal(quantityAfter);
                        cabInventoryProductDao.updateQuantityReal(cabInventoryProduct4Update);
                        quantityOutCurrent=quantityOut;

                        isContinue=false;

                    }


                    CabInventoryProductRecord cabInventoryProductRecord=new CabInventoryProductRecord();
                    cabInventoryProductRecord.setSkuCode(cellInventoryInoutDetailForm.getSkuCode());
                    cabInventoryProductRecord.setEnterpriseCode(enterpriseCode);
                    cabInventoryProductRecord.setQuantity(quantityOutCurrent*-1);
                    cabInventoryProductRecord.setQuantityCurrent(quantityDbCurrent);
                    cabInventoryProductRecord.setQuantityAfter(quantityAfter);
                    cabInventoryProductRecord.setWarehouseId(cabInventoryProduct.getWarehouseId());
                    cabInventoryProductRecord.setType(CabInventoryProductRecord.Type.out4Real);
                    cabInventoryProductRecord.setCreator(creator);
                    cabInventoryProductRecord.setCreatorName(creatorName);
                    inventoryProductRecordService.save(cabInventoryProductRecord);
                    if (!isContinue){
                        break;
                    }
                }

            }
        }
    }

    @Override
    public void checkWarehouseInventory4Load(List<CellInventoryInoutDetailForm> list) {
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        if (CollectionUtil.isNotEmpty(list)){
            for (CellInventoryInoutDetailForm cellInventoryInoutDetailForm:list){
                List<CabInventoryProduct> inventoryProducts=cabInventoryProductDao.selectList(new QueryWrapper<CabInventoryProduct>().eq("sku_code",cellInventoryInoutDetailForm.getSkuCode()).eq("enterprise_code",enterpriseCode).eq("quantity_pack_unit",cellInventoryInoutDetailForm.getQuantityPackUnit()));
//                Integer sum=getSumQuantityReal(inventoryProducts);
                Integer sum=getSumQuantityReal(cellInventoryInoutDetailForm.getSkuCode(),cellInventoryInoutDetailForm.getQuantityPackUnit(),inventoryProducts);
                if (inventoryProducts.size()==0){
                    throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+"无库存");
                }
                if (sum <cellInventoryInoutDetailForm.getQuantity()){
                    throw new BusinessException("库存不足，请先办理入库！");
                    //throw new BusinessException("SKU:"+cellInventoryInoutDetailForm.getSkuCode()+",且包装数量["+cellInventoryInoutDetailForm.getQuantityPackUnit()+"]的当前库存["+sum+"],上货数量为["+cellInventoryInoutDetailForm.getQuantityPack()+"],库存不足");
                }

            }
        }
    }

    private Integer getSumQuantity(List<CabInventoryProduct> inventoryProducts){
        Integer sum=0;
        for (CabInventoryProduct cabInventoryProduct:inventoryProducts){
            sum+=cabInventoryProduct.getQuantity();
        }
        return sum;
    }

    private Integer getSumQuantityReal(String skuCode,Integer quantityPackUnit,List<CabInventoryProduct> inventoryProducts){
        Integer sum=0;
        for (CabInventoryProduct cabInventoryProduct:inventoryProducts){
            sum+=cabInventoryProduct.getQuantity();
        }
//        Integer count=cellInventorySpaceService.count(new QueryWrapper<CellInventorySpace>().eq("sku_code",skuCode));
//        Integer count2=storageInventorySpaceService.count(new QueryWrapper<StorageInventorySpace>().eq("sku_code",skuCode).eq("business_type",StorageInventorySpace.BusinessType.exhibit.getValue()));
//        return count+count2;
        Integer cabQuantity=baseMapper.getCabQuantity(skuCode,quantityPackUnit);
        if (cabQuantity==null){
            cabQuantity=0;
        }
        return sum-cabQuantity;


        /**
        Integer sum=0;
        for (CabInventoryProduct cabInventoryProduct:inventoryProducts){
            sum+=cabInventoryProduct.getQuantityReal();
        }
        return sum;
         */
    }

    @Override
    public List<CabInventoryProduct> totalQuantityBySkuCode(){
        return cabInventoryProductDao.totalQuantityBySkuCode();
    }
}
